<template>
  <div>
    <div ref="container" class="three-container"></div>
    
    <!-- Grading gradients -->
    <div class="gradient-overlay top"></div>
    <div class="gradient-overlay bottom"></div>

    <UI />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue'
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { useAppStore } from './state'
import UI from './components/ui.vue'
import { CarPaintMaterial } from './Carpaint/CarPaintMaterial'

const container = ref<HTMLDivElement>()
const appStore = useAppStore()

// 颜色配置
const COLORS_CONFIG = [
  { color: "red", flake: "silver", perl: "red" },
  { color: "black", flake: "silver", perl: "silver" },
  { color: "#004225", flake: "#199861", perl: "#01632a" },
  { color: "#F8CD02", flake: "#fae20c", perl: "#ffc400" },
  { color: "#9a02f8", flake: "#edcfff", perl: "#e088f9" },
  { color: "#fafafa", flake: "#fafafa", perl: "#fafafa" },
  { color: "#7acaff", flake: "#ffffff", perl: "#013455" },
  { color: "#ff61bd", flake: "#ffbde3", perl: "#ffbde3" },
]

let scene: THREE.Scene
let camera: THREE.PerspectiveCamera
let renderer: THREE.WebGLRenderer
let controls: OrbitControls
let animationId: number
let carModel: THREE.Group | null = null
let carPaintMaterial: CarPaintMaterial | null = null
let simpleMaterial: THREE.MeshStandardMaterial | null = null
let originalMaterial: THREE.Material | null = null
let paintMesh: THREE.Mesh | null = null

// 应用颜色到当前材质
const applyColorToCurrentMaterial = (colorIndex: number) => {
  if (colorIndex < 0 || !paintMesh) return
  
  const selectedColor = COLORS_CONFIG[colorIndex]
  if (!selectedColor) return
  
  console.log('应用颜色:', selectedColor.color, '材质类型:', paintMesh.material.constructor.name)
  
  if (paintMesh.material instanceof CarPaintMaterial) {
    // 高级材质
    paintMesh.material.setColors(selectedColor.color, selectedColor.perl, selectedColor.flake)
  } else if (paintMesh.material instanceof THREE.MeshStandardMaterial) {
    // 简单材质
    paintMesh.material.color.set(selectedColor.color)
    
    // 白色特殊处理
    if (colorIndex === 5) {
      paintMesh.material.metalness = 0.1
      paintMesh.material.roughness = 0.8
    } else {
      paintMesh.material.metalness = 0.5
      paintMesh.material.roughness = 0.5
    }
    
    paintMesh.material.needsUpdate = true
  }
}

onMounted(() => {
  if (!container.value) return

  // 初始化Three.js场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color('#404040')

  // 相机
  camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.set(0, 5, 10)

  // 渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) // 限制像素比以减少内存
  renderer.shadowMap.enabled = true
  renderer.shadowMap.type = THREE.PCFSoftShadowMap
  container.value.appendChild(renderer.domElement)

  // 控制器
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.05

  // 添加地面
  const groundGeometry = new THREE.PlaneGeometry(100, 100)
  const groundMaterial = new THREE.MeshBasicMaterial({ color: '#404040' })
  const ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  ground.position.y = -0.001
  scene.add(ground)

  // 添加灯光
  const ambientLight = new THREE.AmbientLight(0xffffff, 1.2)
  scene.add(ambientLight)

  const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5)
  directionalLight.position.set(5, 10, 5)
  directionalLight.castShadow = true
  scene.add(directionalLight)

  // 添加额外的补光
  const fillLight = new THREE.DirectionalLight(0xffffff, 0.8)
  fillLight.position.set(-5, 5, -5)
  scene.add(fillLight)

  const rimLight = new THREE.DirectionalLight(0xffffff, 0.6)
  rimLight.position.set(0, 5, -10)
  scene.add(rimLight)

  // 配置DRACOLoader
  const dracoLoader = new DRACOLoader()
  dracoLoader.setDecoderPath('/three/examples/jsm/libs/draco/')
  
  // 加载3D模型
  const loader = new GLTFLoader()
  loader.setDRACOLoader(dracoLoader)
  
  loader.load(
    '/car.glb',
    (gltf) => {
      console.log('3D模型加载成功')
      carModel = gltf.scene
      carModel.scale.set(1, 1, 1)
      carModel.position.set(0, 0, 0)
      carModel.rotation.y = -Math.PI / 2
      scene.add(carModel)
      
      // 找到汽车喷漆材质
      carModel.traverse((child: any) => {
        if (child instanceof THREE.Mesh && child.material) {
          if (child.material.name === 'paint' || child.material.name.includes('paint')) {
            paintMesh = child
            originalMaterial = child.material
            
            // 默认创建高级材质
            try {
              carPaintMaterial = new CarPaintMaterial(child.material)
              child.material = carPaintMaterial
              console.log('使用高级材质')
            } catch (error) {
              console.error('高级材质创建失败，使用原始材质:', error)
              carPaintMaterial = null
            }
          }
        }
      })
      
      // 调整相机位置以适应模型
      const box = new THREE.Box3().setFromObject(carModel)
      const center = box.getCenter(new THREE.Vector3())
      const size = box.getSize(new THREE.Vector3())
      const maxDim = Math.max(size.x, size.y, size.z)
      const fov = camera.fov * (Math.PI / 180)
      let cameraZ = Math.abs(maxDim / 2 / Math.tan(fov / 2))
      camera.position.set(center.x, center.y + 2, center.z + cameraZ)
      camera.lookAt(center)
      controls.target.copy(center)
      controls.update()
    },
    (progress) => {
      console.log('加载进度:', (progress.loaded / progress.total * 100) + '%')
    },
    (error) => {
      console.error('3D模型加载失败:', error)
    }
  )

  // 动画循环
  const animate = () => {
    animationId = requestAnimationFrame(animate)
    controls.update()
    renderer.render(scene, camera)
  }
  animate()

  // 窗口大小调整
  const handleResize = () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
  }
  window.addEventListener('resize', handleResize)
  
  // 清理函数
  const cleanup = () => {
    if (animationId) {
      cancelAnimationFrame(animationId)
    }
    if (renderer) {
      renderer.dispose()
    }
    if (scene) {
      scene.traverse((object) => {
        if (object instanceof THREE.Mesh) {
          if (object.geometry) object.geometry.dispose()
          if (object.material) {
            if (Array.isArray(object.material)) {
              object.material.forEach(material => material.dispose())
            } else {
              object.material.dispose()
            }
          }
        }
      })
    }
    window.removeEventListener('resize', handleResize)
  }
  
  // 保存清理函数引用
  ;(window as any).cleanup = cleanup
})

// 监听颜色变化
watch(() => appStore.colorIndex, (newColorIndex) => {
  applyColorToCurrentMaterial(newColorIndex)
})

// 监听材质切换
watch(() => appStore.useAdvancedMaterial, (useAdvanced) => {
  if (!paintMesh) return
  
  console.log('切换材质:', useAdvanced ? '高级材质' : '简单材质')
  
  if (useAdvanced) {
    // 切换到高级材质
    if (carPaintMaterial) {
      paintMesh.material = carPaintMaterial
    } else {
             // 如果高级材质不存在，重新创建
       if (originalMaterial) {
         try {
           carPaintMaterial = new CarPaintMaterial(originalMaterial)
           paintMesh.material = carPaintMaterial
           console.log('重新创建高级材质')
         } catch (error) {
           console.error('高级材质创建失败:', error)
           return
         }
       }
    }
  } else {
         // 切换到简单材质
     if (!simpleMaterial) {
       // 延迟创建简单材质，只在需要时创建
       const defaultColor = originalMaterial && 'color' in originalMaterial 
         ? (originalMaterial.color as THREE.ColorRepresentation)
         : '#ffffff'
       simpleMaterial = new THREE.MeshStandardMaterial({
         color: defaultColor,
         metalness: 0.5,
         roughness: 0.5
       })
     }
    paintMesh.material = simpleMaterial
  }
  
  // 重新应用当前颜色
  setTimeout(() => {
    applyColorToCurrentMaterial(appStore.colorIndex)
  }, 50)
})

// 监听相机位置变化
watch(() => appStore.currentCamera, (newCameraIndex) => {
  if (!carModel) return
  
  const box = new THREE.Box3().setFromObject(carModel)
  const center = box.getCenter(new THREE.Vector3())
  
  switch (newCameraIndex) {
    case 0: // Side
      camera.position.set(center.x + 8, center.y + 2, center.z)
      break
    case 1: // Closeup
      camera.position.set(center.x + 3, center.y + 1, center.z + 2)
      break
    case 2: // Front
      camera.position.set(center.x, center.y + 2, center.z + 8)
      break
    case 3: // Top
      camera.position.set(center.x, center.y + 8, center.z)
      break
    case 4: // Rear
      camera.position.set(center.x, center.y + 2, center.z - 8)
      break
  }
  
  camera.lookAt(center)
  controls.target.copy(center)
  controls.update()
})

onUnmounted(() => {
  if ((window as any).cleanup) {
    ;(window as any).cleanup()
  }
})
</script>

<style scoped>
.three-container {
  width: 100vw;
  height: 100vh;
  position: relative;
}

.gradient-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.gradient-overlay.top {
  background: linear-gradient(to bottom, rgba(0, 22, 59, 0.189) 0%, rgba(255, 255, 255, 0) 50%);
}

.gradient-overlay.bottom {
  background: linear-gradient(to top, rgba(47, 21, 0, 0.58) 0%, rgba(255, 255, 255, 0) 50%);
}
</style>
